package com.shujia.day05;

public class Demo07AbstractClazz {
    public static void main(String[] args) {
        /*
            TODO 抽象类：
                在Java中表示抽象概念的类，可以定义为一个抽象类
                抽象类定义：
                    abstract 用于修饰抽象类
                    对于抽象类，不能进行实例化
                    抽象类可以定义非抽象方法
                抽象方法：
                    在定义方法时，没有给定具体的方法体，并且需要使用abstract修饰
                子类继承抽象类：
                    ① 如果子类不是抽象类并且当抽象类中存在有抽象方法，那么需要通过重写实现其抽象方法的逻辑
                    ② 子类可以继承到抽象类中的非抽象方法


               为什么需要有抽象方法：
                    在定义一个抽象类时，需要定义一个抽象方法，用于标记当前抽象类是存在有该行为的
                        主要的作用是为了规范代码 对于方法的参数以及返回值类型都已经固定了

               抽象类的使用场景：
                    1.当开发代码时，对于具体的功能不知道如何进行运行或定义时，
                            可以先给定一个抽象类，再调用其中的抽象方法 如果当其他开发人员 再开发相关的功能时，就可以
                                重写其对应的代码，实现功能


         */
        Animal animal = new Animal(); // 对于Animal类来说，表示的应该是一个概念性
        animal.run();  // run方法，对于不同的子类，会对其方法进行重写

//        new AbstractAnimal().run();  //抽象类不能实例化
        DogAb dogAb = new DogAb();
        dogAb.run();
        dogAb.eat();

        /*
            TODO 使用抽象类
                可以通过 子实现类（继承抽象类的类）来调用重写/继承的方法
         */
        useAbstractAnimal(new DogAb());

//        new AbstractA();
        C c = new C();

    }

    public static void useAbstractAnimal(AbstractAnimal animal) {
        animal.run();
    }
}

abstract class AbstractAnimal {
    public abstract void run();  // 定义一个抽象方法

    public void eat() {
        System.out.println("动物需要觅食..");
    }
}

class DogAb extends AbstractAnimal {
    @Override
    public void run() {
        System.out.println("狗可以四肢行走...");
    }

//    public abstract void sleep();  // 有抽象方法的类一定是抽象类
}


/*
    TODO Java中如何实现Mysql连接呢？
 */

abstract class DB {
    public abstract Connection createConnection(String url, String user, String passwd);

    public abstract ExecutorRes executorSQL(Connection connection,String sql);

}

class Mysql extends DB{

    @Override
    public Connection createConnection(String url, String user, String passwd) {
        System.out.println("通过"+url+"用户名:"+user+"密码:"+passwd);
        return new MysqlConnection();
    }

    @Override
    public ExecutorRes executorSQL(Connection connection, String sql) {
        return null;
    }
}



abstract class Connection {

}

class MysqlConnection extends Connection{

}


class ExecutorRes {

}

/*
    TODO 抽象类的继承关系
 */

abstract class AbstractA{
    /*
        TODO 抽象类构造方法：
            1.对于抽象方法不能直接使用new 进行调用，但是可以通过创建子类对象的方式来进行调用
     */
    public AbstractA(){
        System.out.println("这是抽象类中的构造方法");
    }

    public abstract void function();
}

abstract class AbstractB extends AbstractA{
    /*
        对于抽象类继承抽象类，可以选择重写其方法，也可以不重写其方法
     */

    @Override
    public void function() {
        System.out.println("这是B抽象类中重写的方法");
    }
}

class C extends AbstractA{

    @Override
    public void function() {
        System.out.println("这是C具体类中重写的方法");
    }
}

class D extends AbstractB{
    /*
        TODO 对于B中继承A的抽象方法已经被重写了，D再继承时，就可以不需要再重写
     */
}